package com.ddh.ddhsanguogame.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // ================ Key操作 ================
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    public Boolean deleteKey(String key) {
        return redisTemplate.delete(key);
    }

    public Long deleteKeys(Collection<String> keys) {
        return redisTemplate.delete(keys);
    }

    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    public Long getExpire(String key, TimeUnit unit) {
        return redisTemplate.getExpire(key, unit);
    }

    // ================ String操作 ================
    public void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public void setValueWithTimeout(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    public Boolean setIfAbsent(String key, Object value) {
        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    public Object getValue(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    // ================ Hash操作 ================
    public void setHash(String key, String field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    public void setAllHash(String key, Map<String, Object> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    public Object getHash(String key, String field) {
        return redisTemplate.opsForHash().get(key, field);
    }

    public Map<String, Object> getAllHash(String key) {
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        return hashOps.entries(key);
    }

    public Long deleteHash(String key, Object... fields) {
        return redisTemplate.opsForHash().delete(key, fields);
    }

    // ================ List操作 ================
    public void setList(String key, Object value, long maxSize) {
        redisTemplate.opsForList().leftPush(key, value);
        if(maxSize > 0) {
            redisTemplate.opsForList().trim(key, 0, maxSize-1);
        }
    }

    /**
     * 永久保存消息到Redis列表（无过期时间，不限制长度）
     * @param key 键
     * @param value 值
     */
    public void setList(String key, Object value) {
        redisTemplate.opsForList().leftPush(key, value);
    }

    public Long getListSize(String key) {
        return redisTemplate.opsForList().size(key);
    }

    public List<Object> getHistory(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }

    // ================ Pub/Sub操作 ================
    public void publishMessage(String channel, Object message) {
        redisTemplate.convertAndSend(channel, message);
    }

    // ================ 高级操作 ================
    public void executePipeline(RedisCallback<?> action) {
        redisTemplate.executePipelined(action);
    }

    public <T> T executeSession(RedisCallback<T> action) {
        return redisTemplate.execute(action);
    }

    // ================ 原子操作 ================
    public Long increment(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    public Double incrementFloat(String key, double delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }
}
